﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JScriptSuite.QA.Lib.System
{
    class BooleanTests
    {
        internal static JResultItem AllTests()
        {
            return JResultItem.CreateInstance("BooleanTests")
                .Push(TrueTests(),
                    FalseTests(),
                    CompareTests(),
                    ICompareTest("ICompareTestFalse", false),
                    ICompareTest("ICompareTestTrue", true),
                    ICompareBoolTest("ICompareBoolTestFalse", false),
                    ICompareBoolTest("ICompareBoolTestTrue", true),
                    IEquatableBoolTest("IEquatableBoolTestFalse", false),
                    IEquatableBoolTest("IEquatableBoolTestTrue", true),
                    EqualsTest("EqualsTestFalse", false),
                    EqualsTest("EqualsTestTrue", true)
                    );
        }

        static JResultItem TrueTests()
        {
            return JResultItem.CreateInstance("TrueTests")
                .Push(true,
                    true.ToString(),
                    (1 == 1),
                    (2 != 1),
                    !true,
                    ("abc" == "abc"));
        }

        static JResultItem FalseTests()
        {
            return JResultItem.CreateInstance("FalseTests")
                .Push(false,
                    false.ToString(),
                    (1 != 1),
                    (2 == 1),
                    !false,
                    ("abc" == "ABC"));
        }

        static JResultItem CompareTests()
        {
            object t = true;
            object f = false;
            return JResultItem.CreateInstance("CompareTests")
                .Push(
                    true.CompareTo(t),
                    true.CompareTo(f),
                    false.CompareTo(t),
                    false.CompareTo(t),
                    false.CompareTo(null),
                    true.CompareTo(null)
                );
        }

        static JResultItem ICompareTest(string name, object value)
        {
            IComparable comparable = value as IComparable;
            return JResultItem.CreateInstance(name)
                .Push(value is IComparable,
                    comparable != null,
                    comparable.CompareTo(null),
                    comparable.CompareTo(false),
                    comparable.CompareTo(true),
                    ExpectedException(delegate() { comparable.CompareTo(0); }),
                    ExpectedException(delegate() { comparable.CompareTo(1); }),
                    ExpectedException(delegate() { comparable.CompareTo(""); }),
                    ExpectedException(delegate() { comparable.CompareTo("x"); })
                );
        }

        static JResultItem ICompareBoolTest(string name, object value)
        {
            IComparable<bool> comparable = value as IComparable<bool>;
            return JResultItem.CreateInstance(name)
                .Push(value is IComparable<bool>,
                    comparable != null,
                    comparable.CompareTo(false),
                    comparable.CompareTo(true)
                );
        }

        static JResultItem EqualsTest(string name, object value)
        {
            return JResultItem.CreateInstance(name)
                .Push(object.Equals(value, 0),
                    value.Equals(0),
                    object.Equals(value, null),
                    value.Equals(null),                
                    object.Equals(1, null),
                    value.Equals(1),                
                    object.Equals(value, -1),
                    value.Equals(-1),                
                    object.Equals(value, ""),
                    value.Equals(""),
                    object.Equals(value, true),
                    value.Equals(true),
                    object.Equals(value, false),
                    value.Equals(false),
                    object.Equals(value, "abc"),
                    value.Equals("abc")              
            );
        }

        static JResultItem IEquatableBoolTest(string name, object value)
        {
            IEquatable<bool> equatable = value as IEquatable<bool>;
            return JResultItem.CreateInstance(name)
                .Push(value is IEquatable<bool>,
                    equatable != null,
                    equatable.Equals(false),
                    equatable.Equals(true)
                );
        }

        static bool ExpectedException(Action a)
        {
            try
            {
                a();
            }
            catch
            {
                return true;
            }

            return false;
        }
    }
}
